package main

// 私有变量、方法的意义在于封装：控制内部数据、保证外部交互的一致性。这样既能促进系统运行的可靠性，也能减少使用者的信息负载。
//
//这样的规定对设计、封装良好的包是友好的，但并不是每个人都有这样的能力，另外对于一些特殊的函数，如：runtime中的memmove函数，在有些场景下，确实是需要的。
//
//因此Go在程序链接阶段给开发者打开了一扇窗，即可以通过go:linkname 指令来链接包内的私有函数。

import (
	"github.com/davecgh/go-spew/spew" // 专门用于数据结构内部套索.
	"unsafe"
) // for go:linkname

// 函数指令参考:https://cloud.tencent.com/developer/article/1422358
//go:noescape
//go:linkname memmove runtime.memmove
//noinspection GoUnusedParameter
func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)

// for mem-move: copy
// memmove更加适合字符串(string)和数组切片之间的数据拷贝场景
// 对于切片之间的数据拷贝，标准库提供的copy函数要更加方便一些
func main() {
	str := "pedro"
	// 注意：这里的len不能为0，否则数据没有分配，就无法复制
	data := make([]byte, 10, 10)
	spew.Dump(str)
	spew.Dump(data)

	memmove((*GoSlice)(unsafe.Pointer(&data)).Ptr, (*GoString)(unsafe.Pointer(&str)).Ptr,
		unsafe.Sizeof(byte(0))*5)
	spew.Dump(str)
	spew.Dump(data)
}
